SQL优化(一)

SQL 优化(一)

优化SQL一般步骤

  1. 通过show status命令了解各种SQL的执行频率
  2. 定位执行效率较低的SQL语句
  3. 通过EXPLAIN分析低效SQL的执行计划
  4. 通过show profile分析SQL
  5. 通过trace分析优化器如何选择执行计划
  6. 确定问题并采取相应的优化措施

通过show status命令了解各种SQL的执行频率

1
show [session|global] status;

该命令提供服务器状态信息

  • session选项:显示当前连接的统计结果
  • global选项:显示自数据库上次启动至今的统计结果

示例:

1
show status like "Com_%";

几个重要的统计参数:

Com_xxx:每个xxx语句执行数,对于所有的存储引擎的表操作都会进行累计

  • Com_select:执行SELECT的次数
  • Com_insert:执行INSERT的次数
  • Com_update:执行UPDATE的次数
  • Com_delete:执行DELETED的次数

Com_commit:记录事务提交的次数

Com_rollback:记录事务回滚的次数

Innodb_rows_xxx:针对InnoDB存储引擎的每个xxx语句所影响的行数

  • Innodb_rows_read:SELECT返回的行数
  • Innodb_rows_inserted:INSERT插入的行数
  • Innodb_rows_updated:更新的行数
  • Innodb_rows_deleted:删除的行数

Connections: 试图连接MySQL服务器的次数

Uptime:服务器工作时间

Slow_queries:慢查询次数

定位执行效率较低的SQL语句

  • 通过慢查询日志定位执行效率较低的SQL语句,用 –log-slow-queries[=file_name]选项启动
  • 使用show processlist命令查看当前MySQL在进行的线程,

通过EXPLAIN分析低效SQL的执行计划

定位到低效的SQL语句之后,通过EXPLAIN或者DESC获取MySQL是如何执行这些语句的

1
EXPLAIN [select|update|delete sql语句]

示例结果

由图中我们可以看出其中有几列是需要我们去理解的

  • select_type:表示SELECT的类型,常见取值如下,
    • SIMPLE:简单类型,就是不使用表连接或者子查询
    • PRIMARY:主查询,就是外层的查询
    • UNION:UNION中的第二个或者后面的查询语句
    • SUBQUERY:子查询中的第一个SELECT
  • table:输出结果集的表
  • type:访问类型
All index range ref eq_ref const,system NULL

All:全表扫描

index:索引全扫描

range:索引范围扫描,常见于<,<=, >, >=, between等操作

ref:使用非唯一索引扫描或唯一索引的前缀扫描,返回匹配某个单独值的记录行,还经常出现在join操作

eq_ref:类似ref,区别在于使用的索引是唯一索引,简单来说就是多表连接中使用primary key或者unique index作为关联条件

const/system:单表中最多有一个匹配行,系统会把匹配行中的其他列作为常数处理

NULL:MySQL不用访问表或者索引,就得到结果

类似的type还有ref_or_null,index_merge,unique_subquery,index_subquery等

  • possible_keys:表示查询时可能使用的索引
  • key:表示实际使用的索引
  • ken_len:使用到的索引字段的长度
  • rows:扫描行的数量
  • Extra:执行情况的说明和描述

通过show profile分析SQL

MySQL从5.0.37版本开始增加了对show profiles和show profile语句的支持,通过have_profiling参数,可以看到当前MSQL是否支持profile

1
select @@have_profiling;

可以通过在Session级别(当前连接时)开启profiling:

1
select @@profiling

通过profile,我们可以清楚了解SQL执行的过程

  • 执行一个select语句当做示例
  • 通过show profiles可以看到当前SQL的Query的ID是多少
  • 执行show profile for query [QueryID] 看到执行过程中线程的每个状态和消耗时间
  • 在获取到最消耗时间的线程状态后,MySQL进一步支持选择all,cpu,block io,context switch,page faults等明细类型查看MySQL在使用什么资源上耗费了过高的时间,如 show profile cpu for query 3;

下面用个例子来说明一下:

  1. 首先执行一个语句 select * from test.tb_account;这是个查找全部的语句

查询

  1. 执行完毕后,通过show profiles语句拿到当前SQL的QueryID为3;

show profiles结果

  1. 通过show profile for query可以看到执行过程中的每个线程的状态和消耗时间

结果

(因为之前那个可视化工具用的太慢,所以换到WorkBench来了,之所以用可视化,还不是因为懒)

  1. 通过第三步获取最消耗时间的线程状态后,通过选择类型来看看MySQL在使用什么资源上耗费过高的时间

执行 show profile cpu for query 3;

cpu profile

通过trace 分析优化器如何选择执行计划

MySQL 5.6提供了对SQL的跟踪trace,通过trace文件进一步了解为什么优化器选择A计划,而不选择B计划。

使用方式:

  1. 打开trace,设置格式为JSON,设置trace最大能够使用的内存大小,避免因内存过小而不能够完整显示

打开trace,设置格式

设置最大内存

  1. 执行想做trace的SQL语句
  2. 检查INFORMATION_SCHEMA.OPTIMIZER_TRACE

检查

确定问题并采取相应优化措施

相关的优化措施会有一篇博客出,至于什么时候出,看笔者的个人努力吧23333333333333333333333

-------------本文结束感谢您的阅读-------------